package com.ambulance.framework.task;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ambulance.common.exception.CustomException;
import com.ambulance.common.utils.DateUtils;
import com.ambulance.framework.MyRedisTemplate;
import com.ambulance.framework.redis.RedisCache;
import com.ambulance.framework.web.domain.AjaxResult;
import com.ambulance.project.biz.dto.web.CarHDInfo;
import com.ambulance.project.biz.entity.*;
import com.ambulance.project.biz.service.CarChannelService;
import com.ambulance.project.biz.service.CarDeviceService;
import com.ambulance.project.biz.service.CarService;
import com.ambulance.project.biz.service.DispatchService;
import com.ambulance.utils.CommonUtils;
import com.ambulance.utils.OkHttp3Util;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.base.Throwables;
import com.google.common.collect.Maps;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.text.SimpleDateFormat;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;

/***
 *  @description
 *  @author zhao
 *  @date: 2020/4/30
 *  @version: v1.0
 */
@Component(value = "hdTask")
public class HdTask {

    private static Logger logger = LoggerFactory.getLogger(HdTask.class);

    @Value("${hd.baseUrl}")
    private String baseUrl = "http://211.162.75.141:52467/";
    @Value(("${hd.user}"))
    private String user = "yansi";
    @Value(("${hd.pwd}"))
    private String pwd = "123456";

    @Value("${hd.loginUrl}")
    private String loginUrl = "iVehicleGPS/loginBsSdk.hd";

    @Value("${hd.carListUrl}")
    private String carListUrl = "iVehicleGPS/vehicle/findVehiclePage.hd";

    @Value("${hd.channelListUrl}")
    private String channelListUrl = "iVehicleGPS/vehicle/getChannelByClickCar.hd";

    @Value("${hd.carGpsUrl}")
    private String carGpsUrl = "iVehicleGPS/vehicle/getVehicleEndPos.hd";

    @Value("${hd.alarmUrl}")
    private String alarmUrl = "iVehicleGPS/alarm/getAlarmTypeMap.hd";

    @Value("${hd.videoUrl}")
    private String videoUrl = "iVehicleGPS/term/videoMoniAutoId.hd";

    @Value("${hd.addCarUrl}")
    private String addCarUrl = "iVehicleGPS/organization/addVehicleByWihteList.hd";

    @Value("${hd.baseVideourl}")
    private String baseVideourl = "rtmp://58.200.131.2:1935/livetv/hunantv";

    @Value("${hd.curOil}")
    private String curOilurl = "iVehicleGPS/statisticalQuery/findOilDetailPage.hd";

    @Value("${hd.mileage}")
    private String mileageurl = "iVehicleGPS/statisticalQuery/findMileageDayStatisticalPage.hd";

    @Autowired
    private OkHttp3Util okHttp3Util;

    @Autowired
    private CarService carService;
    @Autowired
    private CarChannelService carChannelService;
    @Autowired
    private RedisCache redisCache;
    private String alarmIdentity = "HD_ALARM_TYPE_";
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private MyRedisTemplate myRedisTemplate;
    @Autowired
    private CarDeviceService carDeviceService;
    @Autowired
    private DispatchService dispatchService;

    public void hdLogin() {

        try {
            String url = baseUrl + loginUrl;
            HashMap<String, String> param = Maps.newHashMap();
            param.put("username", user);
            param.put("password", pwd);
            okHttp3Util.get(url, param);
        } catch (Exception e) {
            logger.error("登录接口报错 {}", Throwables.getStackTraceAsString(e));
        }
    }

    /**
     * 同步宏电车辆列表---定时任务
     */
    @Transactional()
    public void getCarList() {
        hdLogin();
        final Car car1 = new Car();
        String url = baseUrl + carListUrl;
        //首先离线所有车辆，然后同步对应的车辆信息
        QueryWrapper<Car> updateWhere = new QueryWrapper<>();
        Car updateEntity = new Car();
        updateEntity.setOnline(0);
        carService.update(updateEntity, updateWhere);

        final Object o = okHttp3Util.get(url, null);
        if (ObjectUtil.isNull(o)){
            final JSONObject carObject = JSON.parseObject(o.toString());
            final JSONArray rows = JSON.parseArray(carObject.getString("rows"));
            for (int i = 0; i < rows.size(); i++) {
                QueryWrapper<Car> carQueryWrapper = new QueryWrapper<>();
                final Car car = new Car();
                final JSONObject job = JSON.parseObject(rows.getString(i));
                car.setVin(job.getString("vin"));
                int id = Integer.parseInt(job.getString("id"));

                carQueryWrapper.eq("id", id);
                Car one = carService.getOne(carQueryWrapper);
                boolean flag = false;
                if (!CommonUtils.checkNull(one)) {
                    flag = true;
                }
                car.setId(id);
                car.setDepart(job.getString("departId"));
                car.setDepartName(job.getString("departName"));
                car.setTermSn(job.getString("termSn"));
                car.setExpireDate(getDateTimeOfTimestamp(job.getLong("expireDate")));
                car.setRegisterDate(getDateTimeOfTimestamp(job.getLong("registerDate")));
                car.setModifyDate(getDateTimeOfTimestamp(job.getLong("modifyDate")));
                car.setEnableVehicle(job.getInteger("enableVehicle"));
                car.setOnline(job.getInteger("online"));
                if (flag) {
                    carService.update(car, carQueryWrapper);
                } else {
                    car.setUid(1);
                    carService.save(car);
                }
            }
        }
    }

    /**
     * 同步车辆通道 --定时任务
     */
    @Transactional
    public void getChannelList() {
        //根据车辆信息获取车辆通道
        hdLogin();
        //查询出所有的车辆信息
        final List<Car> list = carService.list();
        for (int i = 0; i < list.size(); i++) {
            final Car car = list.get(i);
            if (!CommonUtils.checkNull(car.getTermSn())) {

                //请求宏电接收新数据
                final HashMap<String, String> map = Maps.newHashMap();
                map.put("termSn", car.getTermSn());
                String url = baseUrl + channelListUrl;
                final Object o = okHttp3Util.get(url, map);
                final JSONArray rows = JSON.parseArray(o.toString());
                if (!CommonUtils.checkNull(rows)) {
                    //先将数据库中的旧数据删除
                    final QueryWrapper<CarChannel> queryWrapper = new QueryWrapper<>();
                    queryWrapper.eq("termSn", car.getTermSn());
                    carChannelService.remove(queryWrapper);
                }
                for (int j = 0; j < rows.size(); j++) {
                    final JSONObject job = JSON.parseObject(rows.getString(j));
                    final CarChannel carChannel = new CarChannel();
                    carChannel.setTermSn(job.getString("termSn"));
                    carChannel.setHdid(job.getString("id"));
                    if (!CommonUtils.checkNull(carChannelService.getOne(new QueryWrapper<CarChannel>().eq("hdid", job.getString("id"))))) {
                        continue;
                    }
                    carChannel.setName(job.getString("name"));
                    carChannel.setChannelNo(job.getInteger("channelNO"));
                    carChannel.setType(job.getString("type"));
                    carChannel.setIcon(job.getString("icon"));
                    carChannel.setVin(car.getVin());
                    carChannelService.save(carChannel);
                }
            }
        }
    }

    //通过车辆id获取通道视频播放地址
    public List<CarChannel> getCarChannelInfo(Integer carId) {
        //登录宏电
        hdLogin();
        //设置请求url
//        String url = baseUrl + videoUrl;
        final Car carInfo = carService.getById(carId);
        if (CommonUtils.checkNull(carInfo)) {
            throw new CustomException("无效的参数");
        }
        final QueryWrapper<CarChannel> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("termSn", carInfo.getTermSn());
        final List<CarChannel> carChannelList = carChannelService.list(queryWrapper);

        for (int i = 0; i < carChannelList.size(); i++) {
            CarChannel channel = carChannelList.get(i);
            CarVideo carVideo = getCarVideo(channel.getTermSn(), channel.getChannelNo() + "");
            /*final HashMap<String, String> map = Maps.newHashMap();
            map.put("termSn", channel.getTermSn());
            map.put("id", String.valueOf(channel.getChannelNo()));
            final Object videoList = okHttp3Util.get(url, map);
            final JSONObject videoObjList = JSON.parseObject(String.valueOf(videoList));*/
            channel.setChannelVideoList(carVideo);

        }
        return carChannelList;
    }

    /**
     * 获取视频流
     *
     * @param termSn
     * @param id
     * @return
     */
    public CarVideo getCarVideo(String termSn, String id) {
        CarVideo item = new CarVideo();
        String url = baseUrl + videoUrl;
        final HashMap<String, String> map = Maps.newHashMap();
        map.put("termSn", termSn);
        map.put("id", id);
        final Object videoList = okHttp3Util.get(url, map);
        final JSONObject videoObjList = JSON.parseObject(String.valueOf(videoList));
        String videoId = videoObjList.getString("videoId");
        if (CommonUtils.checkNull(videoId)) {
            return item;
        }
        item.setVideoId(Long.parseLong(videoId));
        JSONObject dev = videoObjList.getJSONObject("dev");
        if (CommonUtils.checkNull(dev)) {
            return item;
        }
        String devID = dev.getString("id");
        String devChannel = dev.getString("channel");
        item.setDevID(devID);
        item.setDevChannel(devChannel);
        JSONObject svr = videoObjList.getJSONObject("svr");
        if (CommonUtils.checkNull(svr)) {
            item.setSvrUrl(baseVideourl);
            return item;
        }
        String svrUrl = svr.getString("url");
        if (CommonUtils.checkNull(svr.getString("url"))) {
            svrUrl = baseVideourl;
        }
        String svrIp = svr.getString("ip");
        String svrPort = svr.getString("port");
        String svrAddress = svr.getString("address");
        item.setSvrAddress(svrAddress);
        item.setSvrIp(svrIp);
        item.setSvrPort(svrPort);
        item.setSvrUrl(svrUrl);
        return item;
    }

    public CarHDInfo getCarGpsInfo(String vid, String vin) {

        hdLogin();

        String url = baseUrl + carGpsUrl;
        Map<String, String> param = new HashMap<>();
        param.put("vids", vid);
        Object result = okHttp3Util.get(url, param);
        JSONArray jsonArray = JSON.parseArray(result.toString());
        CarHDInfo carHDInfo = new CarHDInfo();
        if (!jsonArray.isEmpty()) {
            JSONObject jsonObject = jsonArray.getJSONObject(0);
            Float latitude = jsonObject.getFloat("latitude");
            Float longitude = jsonObject.getFloat("longitude");
            Float speed = jsonObject.getFloat("speed");
            Integer alarmType = jsonObject.getInteger("alarmType");
            System.out.println(alarmType);
            carHDInfo.setLatitude(latitude);
            carHDInfo.setLongitude(longitude);
            String alarmMessage = redisCache.getCacheObject(alarmIdentity + alarmType);
            if (CommonUtils.checkNull(alarmMessage)) {
                JSONObject alarmMessage1 = getAlarmMessage();
                // 模拟报警发生
//                if(CommonUtils.checkNull(alarmType) || alarmType.equals(524544)){
//                    Random random = new Random();
//                    Integer randoms = random.nextInt(5);
//                    alarmType = randoms <= 1 ? 7 : randoms <= 3 ? 8 : 9;
//                    Integer randomer = random.nextInt(50);
//                  if(randomer > 1){
//                      alarmType = 524544;
//                  }
//                }
                alarmMessage = alarmMessage1.getString(String.valueOf(alarmType));
            }
            carHDInfo.setAlarmMessage(alarmMessage);

            Integer status = 0;
            if (!CommonUtils.checkNull(alarmMessage)) {
                if (alarmMessage.contains("碰撞")) {
                    status = 1;
                } else if (alarmMessage.contains("侧翻")) {
                    status = 2;
                } else if (alarmMessage.contains("存储")) {
                    status = 3;
                } else {
                    status = 4;
                }
            }
            carHDInfo.setStatus(status);
            // 油量
            carHDInfo = getcuil(carHDInfo, vin);
            // 里程
            carHDInfo = getmileage(carHDInfo, vin);
            //车速
            carHDInfo.setSpeed(String.valueOf(speed));
        }
        return carHDInfo;
    }

    public CarHDInfo getmileage(CarHDInfo carHDInfo, String vin) {
        //todo 氧气 --模拟
        //todo 氧气换里程
        String Newmileageurl = baseUrl + mileageurl;
        Map<String, String> curOilparam = new HashMap<>();
        curOilparam.put("page", "1");
        curOilparam.put("rows", "50");
        curOilparam.put("vin", vin);
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM");
        curOilparam.put("month", dateFormat.format(date));
        //todo 获取里程
        Object mileageresult = okHttp3Util.postFormParams(Newmileageurl, curOilparam);
        final JSONObject jsonObject = JSON.parseObject(mileageresult.toString());
        final JSONArray rows = jsonObject.getJSONArray("rows");
        SimpleDateFormat dateFormat1 = new SimpleDateFormat("d");
        if (!CommonUtils.checkNull(rows)) {
            carHDInfo.setOxidation(rows.getJSONObject(0).getString("d" + dateFormat1.format(date)));
            final Car car = new Car();
            car.setOxygen(rows.getJSONObject(0).getString("d" + dateFormat1.format(date)));
            car.setCallbackTime(LocalDateTime.now());
            carService.update(car, new QueryWrapper<Car>().eq("vin", vin));
        } else {
            carHDInfo.setOxidation("0");
        }
        return carHDInfo;
    }

    public CarHDInfo getcuil(CarHDInfo carHDInfo, String vin) {
        //todo 胎压 --模拟
        //todo 胎压换油量
        String NewCurOilurl = baseUrl + curOilurl;
        Map<String, String> curOilparam = new HashMap<>();
        curOilparam.put("page", "1");
        curOilparam.put("rows", "1");
        curOilparam.put("vin", vin);
        Date date = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        curOilparam.put("queryDate", dateFormat.format(date));
        Object curOilresult = okHttp3Util.postFormParams(NewCurOilurl, curOilparam);
        final JSONObject jsonObject = JSON.parseObject(curOilresult.toString());
        final JSONArray rows = jsonObject.getJSONArray("rows");
        if (!CommonUtils.checkNull(rows)) {
            carHDInfo.setPressure(rows.getJSONObject(0).getString("curOil"));
            final Car car = new Car();
            car.setPressure(rows.getJSONObject(0).getString("curOil"));
            carService.update(car, new QueryWrapper<Car>().eq("vin", vin));
        } else {
            carHDInfo.setPressure("0");
        }
        return carHDInfo;
    }

    public CarHDInfo getCarGpsInfoNoAlarm(String vid) {
        hdLogin();
        String url = baseUrl + carGpsUrl;
        Map<String, String> param = new HashMap<>();
        param.put("vids", vid);
        Object result = okHttp3Util.get(url, param);
        if(ObjectUtil.isNull(result)){
            throw new CustomException("宏电服务离线");
        }
        JSONArray jsonArray = JSON.parseArray(result.toString());
        CarHDInfo carHDInfo = new CarHDInfo();
        if (!jsonArray.isEmpty()) {
            JSONObject jsonObject = jsonArray.getJSONObject(0);
            Float latitude = jsonObject.getFloat("latitude");
            Float longitude = jsonObject.getFloat("longitude");
            carHDInfo.setLatitude(latitude);
            carHDInfo.setLongitude(longitude);
        }
        return carHDInfo;
    }

    public AjaxResult getDeviceSyncInfo() {
        final Map device_sync_info = myRedisTemplate.opsForHash().entries("device_sync_info");
        for (Object key : device_sync_info.keySet()) {//keySet获取map集合key的集合  然后在遍历key即可
            String value = device_sync_info.get(key).toString();
            // 截取调度id和序列号  dispatchID_serial
            String dispatchID = key.toString().substring(0, key.toString().indexOf("_"));
            String serial = key.toString().substring(key.toString().length() - key.toString().indexOf("_") - 1);
            System.out.println("-----------------------------------");
            System.out.println(dispatchID);
            System.out.println("-----------------------------------");
            System.out.println(serial);
            System.out.println("key:" + key + " vlaue:" + value);
            System.out.println("-----------------------------------");
            // 判断调度id是否有效
            final Dispatch byId = dispatchService.getById(dispatchID);
            if (CommonUtils.checkNull(byId)) {
                System.out.println("调度ID异常");
                continue;
            }
            // 判断序列号是否有效
            final CarDevice carDevice = carDeviceService.getOne(new QueryWrapper<CarDevice>().eq("serial", serial));
            if (CommonUtils.checkNull(carDevice)) {
                System.out.println("序列号异常");
                continue;
            }
            carDevice.setLastTransferTime(DateUtils.parseString(value));
            carDeviceService.updateById(carDevice);
            System.out.println("-----------------------------------");
            System.out.println("同步成功");
        }
        System.out.println(JSON.toJSONString(device_sync_info));
        myRedisTemplate.delete("device_sync_info");
        return AjaxResult.success();
    }

    /**
     * 报警信息存入redis
     */
    @PostConstruct
    public JSONObject getAlarmMessage() {
        hdLogin();
        try {
            String url = baseUrl + alarmUrl;
            Object result = okHttp3Util.get(url, null);
            if (null != result) {
                JSONObject jsonObject = JSON.parseObject(result.toString());

                Set<String> stringSet = jsonObject.keySet();
                for (String key : stringSet) {
                    redisCache.setCacheObject(alarmIdentity + key, jsonObject.getString(key));
                }
                return jsonObject;
            }

        } catch (Exception e) {

            logger.info("宏电接口报警信息报错 {}", Throwables.getStackTraceAsString(e));

        }
        return null;

    }

    /**
     * @param timestamp
     * @return
     */
    public LocalDateTime getDateTimeOfTimestamp(long timestamp) {
        Instant instant = Instant.ofEpochMilli(timestamp);
        ZoneId zone = ZoneId.systemDefault();
        return LocalDateTime.ofInstant(instant, zone);
    }

//    /**
//     * 添加车辆- 宏电不支持
//     */
//    public Object addCar(BizCar bizCar){
//        hdLogin();
//        String url = baseUrl + addCarUrl;
//        Map<String, String> param = new HashMap<>();
//        param.put("termSn",bizCar.getTermSn());
//        param.put("typeId",bizCar.getTypeId().toString());
//        param.put("modelId",bizCar.getModelId().toString());
//        param.put("departId",bizCar.getDepartId().toString());
//        param.put("color",bizCar.getColor());
//        param.put("registerDate",bizCar.getRegisterDate().toString());
//        param.put("expireDate",bizCar.getExpireDate().toString());
//        final Object postJsonParams = okHttp3Util.postJsonParams(url,JSON.toJSONString(param));
//        System.out.println(postJsonParams);
//        return postJsonParams;
//    }

}
